﻿using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using System.Threading;
using System.IO;

namespace BigNumber.NUnitTests
{

  [TestFixture]
  public class NUnitFastBigNumberTests
  {
    private static int NUMBER_LENGTH = 50;
    [Test]
    public void TestFastBigNumber_Creatoin()
    {
      FastBigNumber number1;
      StdBigNumber number2;
      for (int i = 0; i < TestsHelper.TEST_COUNT; i++)
      {
        string tempNumber = TestsHelper.GenerateRandomNumber(NUMBER_LENGTH, 1);
        number1 = new FastBigNumber(tempNumber);
        number2 = new StdBigNumber(tempNumber);
        Assert.IsTrue(number1.ToString() == number2.ToString());
      }
    }

    [Test]
    public void TestFastBigNumber_Sum()
    {
      FastBigNumber number1;
      StdBigNumber number2;
      for (int i = 0; i < TestsHelper.TEST_COUNT; i++)
      {
        string tempNumber1 = TestsHelper.GenerateRandomNumber(NUMBER_LENGTH, 1);
        string tempNumber2 = TestsHelper.GenerateRandomNumber(NUMBER_LENGTH, 1);
        //Console.WriteLine(tempNumber1 + " + " + tempNumber2);
        number1 = (new FastBigNumber(tempNumber1)) + (new FastBigNumber(tempNumber2));
        number2 = (new StdBigNumber(tempNumber1)) + (new StdBigNumber(tempNumber2));
        Assert.IsTrue(number1.ToString() == number2.ToString(), String.Format("FastBigNumber was {0} and StdBigNumber was {1}", number1.ToString(), number2.ToString()));
      }
    }

    [Test]
    public void TestFastBigNumber_Sub()
    {
      FastBigNumber number1;
      StdBigNumber number2;
      for (int i = 0; i < TestsHelper.TEST_COUNT; i++)
      {
        string tempNumber1 = TestsHelper.GenerateRandomNumber(NUMBER_LENGTH, 1);
        string tempNumber2 = TestsHelper.GenerateRandomNumber(NUMBER_LENGTH, 1);
        //Console.WriteLine(tempNumber1 + " - " + tempNumber2);
        number1 = (new FastBigNumber(tempNumber1)) - (new FastBigNumber(tempNumber2));
        number2 = (new StdBigNumber(tempNumber1)) - (new StdBigNumber(tempNumber2));
        
        Assert.IsTrue(number1.ToString() == number2.ToString(), String.Format("FastBigNumber was {0} and StdBigNumber was {1} while doing {2} - {3}", number1.ToString(), number2.ToString(), tempNumber1, tempNumber2));
      }
    }

    [Test]
    public void TestFastBigNumber_Mul()
    {
      FastBigNumber number1;
      StdBigNumber number2;
      for (int i = 0; i < TestsHelper.TEST_COUNT; i++)
      {
        string tempNumber1 = TestsHelper.GenerateRandomNumber(NUMBER_LENGTH, 1);
        string tempNumber2 = TestsHelper.GenerateRandomNumber(NUMBER_LENGTH, 1);
        number1 = (new FastBigNumber(tempNumber1)) * (new FastBigNumber(tempNumber2));
        number2 = (new StdBigNumber(tempNumber1)) * (new StdBigNumber(tempNumber2));
        Assert.IsTrue(number1.ToString() == number2.ToString(), String.Format("FastBigNumber was {0} and StdBigNumber was {1} when doing {2} * {3}", number1.ToString(), number2.ToString(), tempNumber1, tempNumber2));
      }
    }

    [Test]
    public void TestFastBigNumber_Div()
    {
      FastBigNumber number1;
      StdBigNumber number2;
      Random rnd = new Random();
      for (int i = 0; i < TestsHelper.TEST_COUNT; i++)
      {
        int divisorLength = rnd.Next(2, 50);
        string tempNumber1 = TestsHelper.GenerateRandomNumber(100, 1);
        string tempNumber2 = TestsHelper.GenerateRandomNumber(divisorLength, 0);
        //Console.WriteLine(tempNumber1 + " / " + tempNumber2);
        number1 = (new FastBigNumber(tempNumber1)) / (new FastBigNumber(tempNumber2));
        number2 = (new StdBigNumber(tempNumber1)) / (new StdBigNumber(tempNumber2));
        Assert.IsTrue(number1.ToString() == number2.ToString(), String.Format("FastBigNumber was {0} and StdBigNumber was {1}", number1.ToString(), number2.ToString()));
      }
    }

    [Test]
    public void TestFastBigNumber_Mod()
    {
      FastBigNumber number1;
      StdBigNumber number2;
      Random rnd = new Random();
      for (int i = 0; i < TestsHelper.TEST_COUNT; i++)
      {
        int divisorLength = rnd.Next(2, 50);
        string tempNumber1 = TestsHelper.GenerateRandomNumber(100, 1);
        string tempNumber2 = TestsHelper.GenerateRandomNumber(divisorLength, 0);
        //Console.WriteLine(tempNumber1 + " % " + tempNumber2);
        number1 = (new FastBigNumber(tempNumber1)) % (new FastBigNumber(tempNumber2));
        number2 = (new StdBigNumber(tempNumber1)) % (new StdBigNumber(tempNumber2));
        Assert.IsTrue(number1.ToString() == number2.ToString(), String.Format("FastBigNumber was {0} and StdBigNumber was {1}", number1.ToString(), number2.ToString()));
      }
    }

    [Test]
    public void TestFastBigNumber_Serialization()
    {
      string fileName = "test.tmp";
      FastBigNumber number1;
      FastBigNumber number2;
      List<FastBigNumber> numbers = new List<FastBigNumber>();
      BinaryWriter writer = new BinaryWriter(File.Open(fileName, FileMode.Create));
      try
      {
        for (int i = 0; i < TestsHelper.TEST_COUNT; i++)
        {
          string tempNumber = TestsHelper.GenerateRandomNumber(NUMBER_LENGTH, 1);
          number1 = new FastBigNumber(tempNumber);
          FastBigNumber.Serialize(number1, writer);
          numbers.Add(number1);
          //Assert.IsTrue(number1.ToString() == number2.ToString());
        }
      }
      finally
      {
        writer.Close();
      }

      BinaryReader reader = new BinaryReader(File.Open(fileName, FileMode.Open));
      try
      {
        for (int i = 0; i < TestsHelper.TEST_COUNT; i++)
        {
          number1 = numbers[i];
          number2 = FastBigNumber.Deserialize(reader);
          Assert.IsTrue(number1 == number2);
        }
      }
      finally
      {
        reader.Close();
      }
      File.Delete(fileName);
    }
  }
}
